using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Company.IntegrationTestDslLanguage;
using DslCrossModelFramework;
using DslCrossModelFramework.Environment;
using DslCrossModelFramework.VSPackage;
using NMock2;
using UnitTest.xUnitTests.CrossModelFramework.Mocks;

namespace UnitTest.xUnitTests.CrossModelFramework {
    public static class TestHelper {

        public static Guid testDslPackageGuid = new Guid("349d7662-bf4f-4a81-a35d-8070e6fff9ff");

        public static List<DslToolsPackageInfo> GetPackages() { 
            List<DslToolsPackageInfo> packageInfo = new List<DslToolsPackageInfo>();
            packageInfo.Add(GetTestDslPackageInfo());
            return packageInfo;
        }

        public static DslToolsPackageInfo GetTestDslPackageInfo() {
            DslToolsPackageInfo testPackageInfo = new DslToolsPackageInfo(string.Format("{{{0}}}",testDslPackageGuid.ToString()));
            testPackageInfo.AssemblyName = typeof(IntegrationTestDslLanguageDomainModel).Assembly.FullName;
            testPackageInfo.ClassName = typeof(IntegrationTestDslLanguageDomainModel).AssemblyQualifiedName;
            testPackageInfo.DomainModelMonikerResolverType = typeof(IntegrationTestDslLanguageSerializationBehaviorMonikerResolver).AssemblyQualifiedName;
            testPackageInfo.DomainModelType = typeof(IntegrationTestDslLanguageDomainModel).AssemblyQualifiedName;
            testPackageInfo.FileExtension = "dslIntTest";
            testPackageInfo.IsExportable = true;
            testPackageInfo.ModelElementRootType = typeof(ClassDiagram).AssemblyQualifiedName;
            testPackageInfo.Namespace = typeof(IntegrationTestDslLanguageDomainModel).Namespace;
            testPackageInfo.SerializationBehaviorType = typeof(IntegrationTestDslLanguageSerializationBehavior).AssemblyQualifiedName;
            testPackageInfo.SerializationHelperType = typeof(IntegrationTestDslLanguageSerializationHelper).AssemblyQualifiedName;
            return testPackageInfo;
        }

        public static List<IModelFile> GetModels() {
            List<IModelFile> modelFiles = new List<IModelFile>();
            ReferenceModelFile referenceModelFile1 = GetReferenceModelFile1();
            modelFiles.Add(referenceModelFile1);

            ReferenceModelFile referenceModelFile2 = GetReferenceModelFile2();
            modelFiles.Add(referenceModelFile2);

            ReferenceModelFile referenceModelFile3 = GetReferenceModelFile3();
            modelFiles.Add(referenceModelFile3);

            //ReferenceModelFile referenceModelFile4 = GetReferenceModelFile4();
            //modelFiles.Add(referenceModelFile4);

            return modelFiles;
        }

        private static ReferenceModelFile GetReferenceModelFile4() {
            return new ReferenceModelFile(
                typeof(TestHelper).Assembly.FullName,
                typeof(TestHelper).Assembly.Location,
                typeof(TestHelper).Assembly.GetName().Name,
                "UnitTest.CrossModelFramework.Models.SameSolutionButReferenced.dslIntTest",
                "Foo",
                GetTestDslPackageInfo());
        }

        public static ReferenceModelFile GetReferenceModelFile3() {
            return new ReferenceModelFile(
                Assembly.ReflectionOnlyLoad("ClassLibrary1").FullName,
                Assembly.ReflectionOnlyLoad("ClassLibrary1").Location,
                Assembly.ReflectionOnlyLoad("ClassLibrary1").GetName().Name,
                "ClassLibrary1.IntegrationTestDslLanguage1.dslIntTest",
                "ClassLibrary",
                GetTestDslPackageInfo());
        }

        public static ReferenceModelFile GetReferenceModelFile2() {
            return new ReferenceModelFile(
                Assembly.ReflectionOnlyLoad("ClassDiagram").FullName,
                Assembly.ReflectionOnlyLoad("ClassDiagram").Location,
                Assembly.ReflectionOnlyLoad("ClassDiagram").GetName().Name,
                "ClassDiagram.IntegrationTestDslLanguage2.dslIntTest",
                "ClassDiagram",
                GetTestDslPackageInfo());
        }

        public static ReferenceModelFile GetReferenceModelFile1() {
            return new ReferenceModelFile(
                Assembly.ReflectionOnlyLoad("ClassDiagram").FullName,
                Assembly.ReflectionOnlyLoad("ClassDiagram").Location,
                Assembly.ReflectionOnlyLoad("ClassDiagram").GetName().Name, 
                "ClassDiagram.IntegrationTestDslLanguage1.dslIntTest",
                "ClassDiagram",
                GetTestDslPackageInfo());
        }

        public static IModelDirectory GetModelDirectory() {
            Mockery mocks = new Mockery();
            IModelFileHelper mockHelper = GetModelFileHelperMock(mocks);
            IModelDirectory modelDirectory = new ModelDirectory(mockHelper);
            return modelDirectory;
        }

        public static IModelFileHelper GetModelFileHelperMock(Mockery mockery) {
            IModelFileHelper mockHelper = mockery.NewMock<IModelFileHelper>();
            List<DslToolsPackageInfo> packages = TestHelper.GetPackages();
            Expect.Once.On(mockHelper).Method("GetExportablePackages").Will(Return.Value(packages));
            Expect.Once.On(mockHelper).Method("GetDslModels").With(packages[0]).Will(Return.Value(TestHelper.GetModels()));
            Expect.Once.On(mockHelper).Method("Dispose");
            return mockHelper;
        }

        public static void ResetEnvironment() {
            ((UnitTestEnvironmentConfiguration) EnvironmentConfiguration.Current).ResetEnvironment();
        }

        public static void RegisterEnvironmentConfiguration() {
            if(EnvironmentConfiguration.EnvironmentAvailable) {
                ResetEnvironment();
                EnvironmentConfiguration.ClearRegistrations();
            }
            EnvironmentConfiguration.RegisterEnvironmentConfiguration(new UnitTestEnvironmentConfiguration());
        }
    }
}